import { _decorator, AudioClip, AudioSource, CCFloat, CCInteger, CircleCollider2D, Collider, Collider2D, Component, Contact2DType, director, instantiate, Label, log, Node, Prefab, RichText, UITransform, v2, v3, Vec3 } from 'cc';
import { Joystick } from './Joystick';
const { ccclass, property } = _decorator;

@ccclass('Head')
export class Head extends Component {
    @property(Array(Node))
    bodyArray:Node[] = []; //蛇身体的数量
    @property(Prefab)
    bodyPrefab:Prefab = null; //蛇身预制体
    @property(Prefab)
    foodPrefab:Prefab = null; //食物预制体
    @property(CCInteger)
    bodyNum:number = 2; //初始蛇身数量
    @property(CCFloat)
    bodyDistance:number = 50;//蛇身之间的距离
    speed:number = 200; // 蛇移动的速度
    @property(Vec3)
    snakDir:Vec3;//蛇头的方向
    @property(Node)
    joystick:Node = null;
    previousMoveDir:Vec3;//保存上一帧的移动方向
    Score: number = 0;
    @property(AudioClip)
    eatSound:AudioClip = null;
    @property(AudioClip)
    dieSound:AudioClip = null;
    // UI
    @property(RichText)
    txt_Score:RichText = null;
    @property(Node)
    startPanel:Node = null;
    @property(Node)
    gameOverPanel:Node = null;

    protected onLoad(): void {
        this.bodyArray.push(this.node);
        this.rotateHead(this.node.position);
        this.previousMoveDir = this.node.position.clone().normalize();

        for (let index = 0; index < this.bodyNum; index++) {
            this.getNewBody();
        }
        this.node.position = this.randomPos();

    }
    start() {
        if (!director.isPaused()) {
            director.pause();
        }
        this.schedule(()=>{
            this.moveBody();
        },0.2)
        this.node.parent.addChild(instantiate(this.foodPrefab));

        //开启物理碰撞
        let collider = this.node.getComponent(Collider2D);
        collider.on(Contact2DType.BEGIN_CONTACT,this.onBeginContact,this);

    }

    update(deltaTime: number) {
        this.snakDir = this.joystick.getComponent(Joystick).dir.normalize();
        if (this.snakDir.length() == 0) {
            this.snakDir = this.previousMoveDir.clone().normalize();
        }else{
            this.node.angle = this.joystick.getComponent(Joystick).calculateAngle() - 90;
            this.previousMoveDir = this.snakDir;
        }
        let newPos = this.node.position.clone().add(this.snakDir.clone().multiplyScalar(this.speed * deltaTime));
        this.node.position = newPos;
    }
    //随机蛇身位置
    randomPos(){
        let width = this.node.parent.getComponent(UITransform).contentSize.width - 200;
        let height = this.node.parent.getComponent(UITransform).contentSize.height - 200;
        let x = Math.round(Math.random() * width) - width / 2;
        let y = Math.round(Math.random() * height) - height / 2;
        return v3(x,y,0);
    }

    getNewBody(){
        let newBody = instantiate(this.bodyPrefab);
        if (this.bodyArray.length < 3) {
            let dir = this.node.position.clone().normalize();//归一化，获取方向
            newBody.setPosition(this.node.position.clone().subtract(dir.multiplyScalar(this.bodyDistance)));
        }else{
            let last = this.bodyArray[this.bodyArray.length - 1];
            let lastBody = this.bodyArray[this.bodyArray.length - 2];
            let dir = lastBody.position.clone().subtract(last.position).normalize();
            newBody.setPosition(last.position.clone().subtract(dir.multiplyScalar(this.bodyDistance)));
            newBody.getComponent(CircleCollider2D).group = 16;
        }
        this.node.parent.addChild(newBody);
        this.bodyArray.push(newBody);
    }
    // 蛇头的旋转角度
    rotateHead(headPos){
        let angle = v2(1,0).signAngle(headPos) * 180 / Math.PI;//换成角度
        this.node.angle = angle - 90;
    }

    moveBody(){
        let headPos = this.node.position;//保存蛇头移动前的位置
        for (let index = this.bodyArray.length - 2; index >= 0; index--) {//从后往前开始遍历移动蛇身
            this.bodyArray[index + 1].position = this.bodyArray[index].position;//每一个蛇身都移动到它前面一个节点的位置
        }
        this.bodyArray[1].position = headPos;
    }
    onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D) {
        // 只在两个碰撞体开始接触时被调用一次
        // console.log("====group=",otherCollider.group);
        
        if (otherCollider.group == 4) {
            otherCollider.node.removeFromParent();
            this.Score++;
            this.txt_Score.string = "<color=#000000>" + this.Score.toString() + "</color>";
            // 产生新实物
            let newFood = instantiate(this.foodPrefab);
            this.node.parent.addChild(newFood);
            //更新身体
            this.getNewBody();
            this.node.getComponent(AudioSource).playOneShot(this.eatSound);
        }
        if (otherCollider.group == 8 || otherCollider.group == 16) {
            this.gameOverPanel.active = true;
            this.gameOverPanel.getChildByName("txt_score").getComponent(Label).string = "得分:" + this.Score.toString();
            this.node.getComponent(AudioSource).playOneShot(this.dieSound);
            director.pause();//结束暂停
        }
    }
    // 改变层级
    changeZIndex(){
        let lastIndex = this.node.parent.children.length - 1;
        for (let index = 0; index < this.bodyArray.length; index++) {
            this.bodyArray[index].setSiblingIndex(lastIndex - index);
        }
    }

    // UI
    startGame(){
        
        if (director.isPaused) {
            director.resume();
        }
        this.startPanel.active = false;

    }
    restartGame(){
        director.resume();
        director.loadScene("scene1");

    }
}
